package cn.javass.framework.orm.config;

import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import cn.javass.framework.orm.IDAO;
import cn.javass.framework.orm.annotation.IColumn;
import cn.javass.framework.orm.annotation.ITable;
import cn.javass.framework.orm.annotation.Id;
import cn.javass.framework.orm.impl.BaseDAOImpl;
import cn.javass.framework.orm.mapper.ModelMapper;



public class ORMConfiguration {
	private static ORMConfiguration cfg = null;
	private static Map<String,ModelMapper> modelMapper = new HashMap<String,ModelMapper>();
	
	public static ORMConfiguration configure(String root){
		if(cfg==null){
			synchronized (ORMConfiguration.class) {
				cfg = new ORMConfiguration();
				cfg.builder(root);
			}
		}
		return cfg;
	}
	
	public static ORMConfiguration configure(){
		return configure(null);
	}
	
	private void builder(String rootStr){
		if(rootStr==null){
			rootStr = getClass().getClassLoader().getResource(".").getPath().substring(1);
			
		}
		File root = new File(rootStr);
		parse(root,rootStr.length());
	}
	
	private void parse(File root,int length){
		if(root.isDirectory()){
			for(File file:root.listFiles()){
				parse(file,length);
			}
		}else{
			
			if(root.getName().endsWith(".class")){
				
				String clazzName = root.getAbsolutePath();
				clazzName = clazzName.substring(length,clazzName.length()-6).replace(File.separatorChar, '.');
				processAnnotation(clazzName);
			}
		}
	}
	
	private void processAnnotation(String clazzName){
		try{
			Class clazz = Class.forName(clazzName);
			if(clazz.isAnnotationPresent(ITable.class)){
				makeModelMapper(clazz);
			}
		}catch (Throwable e) {
		}
	}
	
	private void makeModelMapper(Class clazz) throws Exception{
		ModelMapper mm = new ModelMapper();
		ITable tableAnnotation = (ITable)clazz.getAnnotation(ITable.class);
		mm.setClassName(clazz.getName());
		mm.setTableName(tableAnnotation.name());
		
		for(Field field:clazz.getDeclaredFields()){
			if(field.isAnnotationPresent(Id.class)){
				Id id = field.getAnnotation(Id.class);
				mm.setId(field.getName(), id.column());
			}
			
			if(field.isAnnotationPresent(IColumn.class)){
				IColumn column = field.getAnnotation(IColumn.class);
				mm.addColumn(field.getName(), column.column());
			}
		}
		modelMapper.put(clazz.getName(),mm);
	}
	
	
	
	public ModelMapper getModelMapper(String clazzName){
		return modelMapper.get(clazzName);
	}
	
	
	
	public static IDAO getDao(){
		return new BaseDAOImpl();
	}
	
	public static void main(String[] args) throws Exception{
	
	}
	
}
